package com.xuecheng.learning.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.constants.OrdersConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.LearningProgressDto;
import com.xuecheng.commons.model.dto.RecordDto;
import com.xuecheng.commons.model.vo.*;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.api.ContentClient;
import com.xuecheng.learning.domain.CourseRecord;
import com.xuecheng.learning.mapper.CourseRecordMapper;
import com.xuecheng.learning.service.CourseRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.media.api.MediaClient;
import com.xuecheng.search.api.SearchClient;
import com.xuecheng.web.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 选课记录 服务实现类
 * </p>
 *
 * @author HuangYuwu
 * @since 2022-09-16
 */
@Service
@Slf4j
public class CourseRecordServiceImpl extends ServiceImpl<CourseRecordMapper, CourseRecord> implements CourseRecordService {

    @Autowired
    private SearchClient searchClient;
    @Autowired
    private MediaClient mediaClient;
    @Autowired
    private ContentClient contentClient;

    /**
     * 获取当前课程发布的学习进度
     *
     * @param coursePubId
     * @return
     */
    @Override
    public ResponseResult myCourseRecord(Long coursePubId) {
        Long userId = AuthInfoHolder.getUserId();
        LambdaQueryWrapper<CourseRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseRecord::getCoursePubId, coursePubId);
        queryWrapper.eq(CourseRecord::getUserId, userId);
        CourseRecord courseRecord = this.getOne(queryWrapper);
        if (ObjectUtil.isEmpty(courseRecord)) {
            log.info(String.valueOf(courseRecord == null));
            return ResponseResult.okResult();
        }
        CourseRecordVo courseRecordVo = BeanHelper.copyProperties(courseRecord, CourseRecordVo.class);
        return ResponseResult.okResult(courseRecordVo);
    }

    /**
     * （支付成功）保存或更新选课记录
     *
     * @param recordDto
     * @return
     */
    @Override
    public ResponseResult saveRecord(RecordDto recordDto) {
        LambdaQueryWrapper<CourseRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseRecord::getCoursePubId, recordDto.getCoursePubId());
        queryWrapper.eq(CourseRecord::getUserId, recordDto.getUserId());
        CourseRecord courseRecord = this.getOne(queryWrapper);
        if (ObjectUtil.isNotEmpty(courseRecord)) {
            //已试听免费课程 修改状态为已支付
            courseRecord.setPaid(OrdersConstants.PAID);
            this.updateById(courseRecord);
            return ResponseResult.okResult();
        }
        //没有试听 直接购买
        courseRecord = new CourseRecord();
        ResponseResult<CoursePubIndexVo> result = searchClient.findById(recordDto.getCoursePubId().toString());
        if (result.getCode() != 0) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        CoursePubIndexVo pubIndexVo = result.getData();
        courseRecord.setUserId(AuthInfoHolder.getUserId());
        courseRecord.setUserName(AuthInfoHolder.getAuthInfo().getUserName());
        courseRecord.setCompanyId(AuthInfoHolder.getCompanyId());
        courseRecord.setCourseId(recordDto.getCoursePubId());
        courseRecord.setCoursePubId(recordDto.getCoursePubId());
        courseRecord.setCoursePubName(pubIndexVo.getName());
        courseRecord.setTeachmode(pubIndexVo.getTeachmode());
        courseRecord.setCreateDate(DateUtil.date());
        courseRecord.setPaid(OrdersConstants.PAID);
        this.save(courseRecord);
        return ResponseResult.okResult();
    }

    /**
     * 课程详情页查询媒资播放地址
     *
     * @param coursePubId
     * @param mediaId
     * @param teachplanId
     * @return
     */
    @Override
    public ResponseResult resourceUrl(Long coursePubId, Long mediaId, Long teachplanId) {
        // 1.查询课程发布是否收费
        ResponseResult<CoursePubVo> pubVoResponseResult = contentClient.findById(coursePubId);
        if (pubVoResponseResult.getCode() != 0) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        // 201000 免费、201001 收费
        // 2.如果课程收费
        CoursePubVo coursePubVo = pubVoResponseResult.getData();
        if (coursePubVo.getCharge().equals(CourseConstants.CHARGE_YES)) {
            // 在查询课程计划是否收费
            ResponseResult<TeachplanVo> teachplanVoResponseResult = contentClient.findTeachplanById(teachplanId);
            if (teachplanVoResponseResult.getCode() != 0) {
                throw new BusinessException(ErrorCode.ERROR);
            }
            // 0 不支持 1支持预览
            TeachplanVo teachplanVo = teachplanVoResponseResult.getData();
            if (teachplanVo.getIsPreview().equals("0")) {
                // 3.如果不支持预览，查询用户是否支付
                // （根据用户id和课程发布id和支付查询选课记录）
                LambdaQueryWrapper<CourseRecord> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(CourseRecord::getUserId, AuthInfoHolder.getUserId());
                queryWrapper.eq(CourseRecord::getCoursePubId, coursePubId);
                queryWrapper.eq(CourseRecord::getPaid, 1);
                CourseRecord one = this.getOne(queryWrapper);
                // 查询用户是否支付
                if (one == null) {
                    throw new BusinessException(ErrorCode.NOTPLAY);
                }
            }
        }
        // 4.表示此课程：免费、收费（试看）、已付费，返回媒资播放地址
        ResponseResult<ResourceVo> result = mediaClient.findMediaUrl(mediaId);
        if (result.getCode() != 0) {
            throw new BusinessException(ErrorCode.ERROR);
        }
        ResourceVo resourceVo = result.getData();
        return ResponseResult.okResult(resourceVo);
    }

    /**
     * 免费课程新增选课，或者更新学习进度
     *
     * @param learningProgressDto
     * @return
     */
    @Override
    public ResponseResult progress(LearningProgressDto learningProgressDto) {
        AuthInfo authInfo = AuthInfoHolder.getAuthInfo();
        // 1.当前用户是否有选课记录
        LambdaQueryWrapper<CourseRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseRecord::getUserId, authInfo.getUid());
        queryWrapper.eq(CourseRecord::getCoursePubId, learningProgressDto.getCoursePubId());
        CourseRecord courseRecord = this.getOne(queryWrapper);
        // 2.如果有
        if (courseRecord != null) {
            // 更新学习进度（课程计划）
            courseRecord.setTeachplanId(learningProgressDto.getTeachPlanId());
            courseRecord.setTeachplanName(learningProgressDto.getTeachPlanName());
            this.updateById(courseRecord);
        } else {
            // 3.如果没有，构建选课记录，保存数据库

            ResponseResult<CoursePubIndexVo> responseResult = searchClient.findById(learningProgressDto.getCoursePubId().toString());
            if (responseResult.getCode() != 0) {
                throw new BusinessException(ErrorCode.ERROR);
            }
            CoursePubIndexVo coursePubIndexVo = responseResult.getData();
            courseRecord = new CourseRecord();
            courseRecord.setUserId(authInfo.getUid());
            courseRecord.setUserName(authInfo.getUserName());
            courseRecord.setCompanyId(authInfo.getCompanyId());
            courseRecord.setCourseId(coursePubIndexVo.getCourseId());
            courseRecord.setCoursePubId(coursePubIndexVo.getCourse_id());
            courseRecord.setCoursePubName(coursePubIndexVo.getName());
            courseRecord.setTeachmode(coursePubIndexVo.getTeachmode());
            courseRecord.setTeachplanId(learningProgressDto.getTeachPlanId());
            courseRecord.setTeachplanName(learningProgressDto.getTeachPlanName());
            courseRecord.setCreateDate(DateUtil.date());
            courseRecord.setPaid(OrdersConstants.NOT_PAID);
            this.save(courseRecord);
        }
        return ResponseResult.okResult();
    }


}
